package com.vanke.kotlin_mvp.data.local

import android.content.ContentValues
import android.content.Context
import com.vanke.kotlin_mvp.data.Task
import com.vanke.kotlin_mvp.data.TaskDataSource
import com.vanke.kotlin_mvp.data.local.TasksTable.TaskEntry.COLUMN_NAME_COMPLETED
import com.vanke.kotlin_mvp.data.local.TasksTable.TaskEntry.COLUMN_NAME_DESCRIPTION
import com.vanke.kotlin_mvp.data.local.TasksTable.TaskEntry.COLUMN_NAME_ENTRY_ID
import com.vanke.kotlin_mvp.data.local.TasksTable.TaskEntry.COLUMN_NAME_TITLE
import com.vanke.kotlin_mvp.data.local.TasksTable.TaskEntry.TABLE_NAME

/**
 * @name Kotlin_MVP
 * @package name：com.vanke.kotlin_mvp.data.local
 * @class describe
 * @anthor shiyuchuan
 * @time 2017/8/17 11:27
 */
class TasksLocalDataSource private constructor(val dbHelper: TasksDbHelper = TasksDbHelper.instance) : TaskDataSource {

    override fun getTasks(callback: TaskDataSource.LoadTaskCallback) {
        val tasks = ArrayList<Task>()
        val projection = arrayOf(TasksTable.TaskEntry.COLUMN_NAME_ENTRY_ID, TasksTable.TaskEntry.COLUMN_NAME_TITLE,
                TasksTable.TaskEntry.COLUMN_NAME_DESCRIPTION, TasksTable.TaskEntry.COLUMN_NAME_COMPLETED)
        dbHelper.use {
            val cursor = query(TABLE_NAME, projection, null, null, null, null, null)
            with(cursor) {
                while (moveToNext()) {
                    val itemId = getString(getColumnIndexOrThrow(COLUMN_NAME_ENTRY_ID))
                    val title = getString(getColumnIndexOrThrow(COLUMN_NAME_TITLE))
                    val description = getString(getColumnIndexOrThrow(COLUMN_NAME_DESCRIPTION))
                    val task = Task(title, description, itemId).apply {
                        isCompleted = getInt(getColumnIndexOrThrow(COLUMN_NAME_COMPLETED)) == 1
                    }
                    tasks.add(task)
                }

                if (tasks.isEmpty()) {
                    callback.onTaskLoaded(tasks)
                } else {
                    callback.onDataNotAvailable()
                }
                close()
            }
        }
    }

    override fun getTask(taskId: String, callback: TaskDataSource.GetTaskCallback) {
        dbHelper.use {
            val projection = arrayOf(COLUMN_NAME_ENTRY_ID, COLUMN_NAME_TITLE,
                    COLUMN_NAME_DESCRIPTION, COLUMN_NAME_COMPLETED)

            val cursor = query(TABLE_NAME, projection, "$COLUMN_NAME_ENTRY_ID LIKE ?",
                    arrayOf(taskId), null, null, null)
            with(cursor) {
                if (moveToFirst()) {
                    val itemId = getString(getColumnIndexOrThrow(COLUMN_NAME_ENTRY_ID))
                    val title = getString(getColumnIndexOrThrow(COLUMN_NAME_TITLE))
                    val desc = getString(getColumnIndexOrThrow(COLUMN_NAME_DESCRIPTION))
                    val task = Task(title, desc, itemId).apply {
                        isCompleted = getInt(getColumnIndexOrThrow(COLUMN_NAME_COMPLETED)) == 1
                    }
                    callback.onTaskLoaded(task)
                } else {
                    callback.onDataAvailable()
                }

                close()
            }
        }
    }

    override fun saveTask(task: Task) {
        val values = ContentValues().apply {
            put(COLUMN_NAME_ENTRY_ID, task.id)
            put(COLUMN_NAME_TITLE, task.title)
            put(COLUMN_NAME_DESCRIPTION, task.description)
            put(COLUMN_NAME_COMPLETED, task.isCompleted)
        }
        dbHelper.use {
            insert(TABLE_NAME, null, values)
        }
    }

    override fun completeTask(task: Task) {
        val values = ContentValues().apply {
            put(COLUMN_NAME_COMPLETED, true)
        }
        dbHelper.use {
            update(TABLE_NAME, values, "$COLUMN_NAME_ENTRY_ID LIKE ?", arrayOf(task.id))
        }
    }

    override fun completeTask(taskId: String) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun activateTask(task: Task) {
        val values = ContentValues().apply {
            put(COLUMN_NAME_COMPLETED, false)
        }
        dbHelper.use {
            update(TABLE_NAME, values, "$COLUMN_NAME_ENTRY_ID LIKE ?", arrayOf(task.id))
        }
    }

    override fun activateTask(taskId: String) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun clearCompletedTasks() {
        val selection = "$COLUMN_NAME_COMPLETED LIKE ?"
        val selectionArgs = arrayOf("1")

        dbHelper.use {
            delete(TABLE_NAME, selection, selectionArgs)
        }
    }

    override fun refreshTasks() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun deleteAllTasks() {
        dbHelper.use {
            delete(TABLE_NAME, null, null)
        }
    }

    override fun deleteTask(taskId: String) {
        val selection = "$COLUMN_NAME_ENTRY_ID LIKE ?"
        val selectionArgs = arrayOf(taskId)
        dbHelper.use {
            delete(TABLE_NAME, selection, selectionArgs)
        }
    }

    companion object {
        private lateinit var INSTANCE: TasksLocalDataSource
        private var needsNewInstance = true

        fun getInstance(context: Context): TasksLocalDataSource {
            if (needsNewInstance) {
                INSTANCE = TasksLocalDataSource()
                needsNewInstance = false
            }
            return INSTANCE
        }
    }
}